註:本文同步刊載在Medium,若習慣Medium的話亦可去那邊看呦!
接下來我們要聊到日期與時間的處理相關模組:
datetime跟time。
請想像一下,在人生當中,是不是常常有要算日子和時間的時候?
不論是算退伍還有多少天;
算紀念日520天是什麼時候;
算紀念日1000天是什麼時候;
算紀念日2000天是什麼時候......XD
我們可以利用Python的datetime模組來幫忙計算時間日期與時間差,
這樣子就不會在被問今天是什麼日子的時候答不出來了(吧)!
datetime當中就有date物件和time物件,
接下來的示範還是屬於datetime模組的範疇,
請大家不要跟後面的time模組搞混歐!
我們先來看看操作日期的date物件的用法:
>>> from datetime import date
>>> doubleten = date(2020, 10, 10) # 順序是年/月/日
>>> doubleten.year, doubleten.month, doubleten.day
(2020, 10, 10)
# 用isoformat()和str()都可以轉成用"-"連接的字串
>>> doubleten.isoformat(), str(doubleten)
('2020-10-10', '2020-10-10')
>>> today = date.today() # today()會取到今天
>>> str(today) # isoformat格式會補0
'2020-10-01'
# 2020-10-01是星期四,weekday的記法是0(星期一)~6(星期日)
# isoweekday的記法則是1(星期一)~7(星期日)
>>> today.weekday(), today.isoweekday()
(3, 4)
# strftime可用來格式化想要的顯示樣態和目標
>>> doubleten.strftime('%Y--%m--%d, WeekDay: %a')
'2020--10--10, WeekDay: Sat'
關於strftime以及後面常見的格式,
大體上會跟一般通用的表示法相同,
例如%Y代表年,%m代表月,%d代表日,%a則代表星期幾的縮寫;
其他還有%H(小時)、%M(分)、%S(秒)等等,
可以參考strftime() 和 strptime() Format Codes。
datetime中的time物件操作方式也很類似:
>>> from datetime import time
>>> time() # datetime的time.time()預設是從0開始
datetime.time(0, 0)
>>> now = time()
>>> now.isoformat()
'00:00:00'
>>> now = time(0,0,0,38) # 最小單位到微秒(百萬分之一秒,也就是10e-6)
>>> now.microsecond # 取微秒
38
>>> now = time(hour=19, second=50)
>>> str(now)
'19:00:50'
>>> now.strftime('%H-%M') # 同樣可以適用strftime
'19-00'
或者,兩者都要的話,
可以直接使用datetime.datetime物件!
>>> from datetime import datetime
>>> datetime.today() # 現在的時間,計到微秒
datetime.datetime(2020, 10, 1, 17, 37, 7, 490703)
>>> datetime.utcnow() # UTC標準時間(所以台灣是+8,看出來了嗎?)
datetime.datetime(2020, 10, 1, 9, 37, 43, 823644)
# str這邊和isoformat就會有點不一樣了,isoformat會用"T"來分隔。
>>> str(datetime.now())
'2020-10-01 17:39:03.953659'
>>> datetime.now().isoformat()
'2020-10-01T17:39:23.671787'
讀者可能會問:
「不對阿,說好的算紀念日呢?」
要計算日期差距相關的處理,
我們要用到datetime的另一個物件:
timedelta。
timedelta的建立很簡單,就是timedelta(時間差)。
下面我們假設小亦向阿啾在今年的情人節2/14告白並成功了,
接下來我們先來算一下到現在(10/1)為止,
他們已經經過了幾天,到後面的紀念日又還有多久呢?
>>> from datetime import date, datetime, time ,timedelta
>>> valentine = date(2020, 2, 14)
>>> today = date.today()
>>> romanticlen = today - valentine # date相減會變成timedelta
# 算一算交往時間吧!
>>> romanticlen
datetime.timedelta(days=230)
# 小亦要記得的幾個紀念日
>>> remember = [100, 200, 520, 1000, 2000]
# 注意timedelta也可以用乘上數字來和定點日期相加減計算,相當有彈性
>>> memorialday = [valentine + timedelta(days=i) for i in remember]
>>> memorialday # 咦?這時間怎麼好像有的已經過了?
[datetime.date(2020, 5, 24), datetime.date(2020, 9, 1), datetime.date(2021, 7, 1
8), datetime.date(2022, 11, 10), datetime.date(2025, 8, 6)]
>>> diff = [i - today for i in memorialday] # 來減看看!
>>> diff # 小亦你很糟糕歐,有兩個紀念日已經過了!阿啾會哭哭呦XD
[datetime.timedelta(days=-130), datetime.timedelta(days=-30), datetime.timedelta
(days=290), datetime.timedelta(days=770), datetime.timedelta(days=1770)]
講完了datetime,我們現在來講time模組。
time模組比較簡單一點點,基本上最常用到的就是time.time()。
time.time()會給出Unix標準時間,
也就是以1970年1月1號起算到目前為止帶小數點的總秒數(不用背,不會考XD)。
如果使用localtime()的話,則會換算成現在所在時區的時間。
>>> import time
>>> time.time()
1601547391.7189288
>>> time.localtime() # 筆者電腦目前是2020年10月1日下午6點16分
time.struct_time(tm_year=2020, tm_mon=10, tm_mday=1, tm_hour=18, tm_min=16, tm_s
ec=34, tm_wday=3, tm_yday=275, tm_isdst=0)
上面範例中的struct_time是time的另一個物件,
作用是可以用來給定一個指定的時間方便處理。
我們也可以使用time.ctime()或time.strftime(格式化字串, 時間),
將其轉換成易讀的字串。
>>> now = time.localtime()
>>> time.ctime()
'Thu Oct 1 18:22:46 2020'
>>> time.strftime('現在是%A, %Y年%m月%d日的%H時%M分%S秒', now)
'現在是Thursday, 2020年10月01日的18時22分35秒'
不同的國家語系,給出來的縮寫等會不同,
如果要再精細轉換的話,可以使用local進行setlocale()的操作,
有興趣的話,可以再進一步研究一下用法。
但最常被簡單用到的方式還是time.time()跟time.sleep()了!
通常狀況下,我們會在跑完一段想測量的程式以後,
使用time.time()的差值來計算時間。
time.sleep()則可以讓程式暫時停止執行指定的秒數,
待時間到才繼續運作。
我們拿前面的os的程式來修改一下測試這兩個方法,
會發現多次測試下,扣掉10秒以後,(因為10秒是我們睡掉的XD)
耗時其實差距蠻大的。
要取得一個比較良好的數據,
就可能要用迴圏來多測幾次,再取平均值。
import os, time
start = time.time()
for path, dirs, files in os.walk('.'):
print(path)
for f in files:
print(os.path.join(path, f))
for d in dirs:
print(os.path.join(path, d))
time.sleep(10) # 睡10秒鐘(可以給小數)
end = time.time()
print("總耗時:%f" % (end - start))
C:\Users\Desolve\utils>python fromzero.py
.
.\bookstore.json
.\check.py
.\fromzero.py
.\poem.txt
.\schedule.py
.\__init__.py
.\csv
.\json
.\__pycache__
.\csv
.\csv\student.csv
.\csv\student_dic.csv
.\json
.\json\classA.json
.\__pycache__
.\__pycache__\check.cpython-38.pyc
.\__pycache__\schedule.cpython-38.pyc
.\__pycache__\__init__.cpython-38.pyc
總耗時:10.003572
C:\Users\Desolve\utils>python fromzero.py
.
.\bookstore.json
.\check.py
.\fromzero.py
.\poem.txt
.\schedule.py
.\__init__.py
.\csv
.\json
.\__pycache__
.\csv
.\csv\student.csv
.\csv\student_dic.csv
.\json
.\json\classA.json
.\__pycache__
.\__pycache__\check.cpython-38.pyc
.\__pycache__\schedule.cpython-38.pyc
.\__pycache__\__init__.cpython-38.pyc
總耗時:10.002572
最後我們來做個練習吧!
那麼,我們就明天見囉!